#include "board_base.h"

#include "bsp_uart.h"
#include "SEGGER_RTT.h"
#include "ITM.h"
#include "tim.h"
#include "gpio.h"
#include "log.h"
#include "Stepper.hpp"
#include "w25qxx.h"
/*-----------------------------------------------------------------------
|                                define                                 |
-----------------------------------------------------------------------*/
#define BOARDTAG "Board"
#define Board_Firmware_ProjectName "STM32F103ZE_RTOS_Project"
#define Board_Firmware_Version  STR(1.0)
#define Board_Firmware_Auther  "liuzhihua"
#define Board_System_Frequnce   SystemCoreClock
const char LINESTR[] = "--------------------------------------------------------------------------------\n";
#define STR(str) #str
TimerHandle_t BuzzerTimer;

/*-----------------------------------------------------------------------
|                               Function                                |
-----------------------------------------------------------------------*/

/**
 * @brief 记录归零，开始测量时间
 * @param timecnt 用来记录时间的变量
 * @retval uint32_t 
 */
void bsp_MesureTimeStart(uint32_t *timecnt)
{
	*timecnt = HAL_GetTick();
}

/**
 * @brief 测量时间
 * @param old_counter 用来记录时间的变量
 * @retval uint32_t 上次使用到这次使用的时间(ms)
 */
uint32_t bsp_MesureTime(uint32_t *old_counter)
{
	uint32_t counter, couter_current;
	couter_current = HAL_GetTick();
	if (couter_current > *old_counter)//没有溢出
		counter = couter_current - *old_counter;
	else//发生过溢出
		counter = couter_current + 0XFFFFFFFF - *old_counter;
	*old_counter = couter_current;
	return (counter);
}


void board_info_output(void)
{
	LOGS("JLink RTT Start\n");
	LOGS(LINESTR);
	LOG_INFO(BOARDTAG, "ProjectName :  %s\n",Board_Firmware_ProjectName);
	LOG_INFO(BOARDTAG, "Version     :  %s\n",Board_Firmware_Version);
	LOG_INFO(BOARDTAG, "Auther      :  %s\n",Board_Firmware_Auther);
	LOG_INFO(BOARDTAG, "SystemClock :  %d\n",Board_System_Frequnce);
	LOG_INFO(BOARDTAG, "Extern Flash: W25Q%d[ID:%d|FlashSize:%dKB]\n",w25qxx.BlockCount/2, w25qxx.ID, w25qxx.BlockCount * (w25qxx.BlockSize/1024));
	LOGS(LINESTR);
}

void Buzzer_Start(int _time_)
{

	HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_SET);
	xTimerChangePeriod(BuzzerTimer, pdMS_TO_TICKS(_time_),0);//修改定时器周期
	if(BuzzerTimer)
	{
		xTimerStart(BuzzerTimer, 0);
	}

}
void Buzzer_Stop(TimerHandle_t xTimer)
{
	HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_RESET);
}
/**
 * @brief 板载资源初始化
 */
void board_base_init(void)
{
	// HAL_TIM_Base_Start(&htim5);
	// HAL_TIM_Base_Start(&htim2);
	HAL_TIM_Base_Start(&htim3);//PB0,PB1
	UART_BSP_Init();
	SEGGER_RTT_Init();
	DWT_Init();
	W25qxx_Init();
	LogSetLevel(LOG_LEVEL_NONE);
 	board_info_output();
	bsp_stepper_init();
	/* 使用动态分配内存的方法创建定时器
	* pcTimerName:定时器名字, 用处不大, 一般在调试时用到
	* xTimerPeriodInTicks: 周期, 以Tick为单位
	* uxAutoReload: 类型, pdTRUE表示自动加载, pdFALSE表示一次性
	* pvTimerID: 回调函数可以使用此参数, 比如分辨是哪个定时器
	* pxCallbackFunction: 回调函数
	* 返回值: 成功则返回TimerHandle_t, 否则返回NULL
	*/	
	BuzzerTimer = xTimerCreate( "BuzzerBeepTimer",
								50 / portTICK_PERIOD_MS,
								pdFALSE,
								0,
								Buzzer_Stop);
	Beep(50);

}

Stepper stepper1(3200, -3200*90/2, 3200*90/2);
Stepper stepper2(3200, -3200*90/2, 3200*90/2);
void bsp_stepper_init(void)
{
	stepper1.attachDirPin(Stepper1Dir_GPIO_Port, Stepper1Dir_Pin, GPIO_PIN_SET);
	stepper1.attachEnPin(Stepper1EN_GPIO_Port, Stepper1EN_Pin, GPIO_PIN_SET);
	stepper1.attachPulsePin(GPIOA, GPIO_PIN_0, &htim2, TIM_CHANNEL_1);

	stepper2.attachDirPin(Stepper2Dir_GPIO_Port, Stepper2Dir_Pin, GPIO_PIN_SET);
	stepper2.attachEnPin(Stepper2EN_GPIO_Port, Stepper2EN_Pin, GPIO_PIN_SET);
	stepper2.attachPulsePin(GPIOA, GPIO_PIN_2, &htim5, TIM_CHANNEL_3);

	stepper1.setDriverEnableStatus(1);
	stepper2.setDriverEnableStatus(1);

	stepper1.limitsw1.attachPin(StepperLSW1_GPIO_Port, StepperLSW1_Pin, GPIO_PIN_RESET);
	stepper2.limitsw1.attachPin(StepperLSW2_GPIO_Port, StepperLSW2_Pin, GPIO_PIN_RESET);
	// stepper1.setSpeed(0.1);
	// stepper2.setSpeed(200);

}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	// LOG_DBG(BOARDTAG,"PulseTEST %p, ch:%d\n",htim,htim->Channel);
	StepperDriverPulseFinishedCallback(&stepper1.driver, htim);
	StepperDriverPulseFinishedCallback(&stepper2.driver, htim);
}

/**
  * @brief  EXTI line detection callbacks.
  * @param  GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{

	stepper1.extiCallback(GPIO_Pin);
	stepper2.extiCallback(GPIO_Pin);

}

